package com.storm.demo;


import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import org.springframework.beans.BeansException;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.ClassPathResource;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Properties;

public class BeanRepository {

    @Setter
    private static AnnotationConfigApplicationContext BEAN_FACTORY;

    @Getter
    private static Properties PROPERTIES;


    public static <T> T getBean(String name, Class<T> requiredType)throws BeansException{
        return BEAN_FACTORY.getBean(name, requiredType);
    }


    public static <T> T getBean(Class<T> requiredType)throws BeansException {
        return BEAN_FACTORY.getBean(requiredType);
    }


    public static <T> Map<String,T> getBeansOfType(Class<T> requiredType){
        return BEAN_FACTORY.getBeansOfType(requiredType);
    }

    @SneakyThrows
    public static Class<?> loadClass(String name){
        return BEAN_FACTORY.getClassLoader().loadClass(name);
    }

    private static PropertySourcesPlaceholderConfigurer loadPlaceholderConfigurer(String path){
        PropertySourcesPlaceholderConfigurer pph = new PropertySourcesPlaceholderConfigurer();
        pph.setLocation(new ClassPathResource(path));
        pph.setFileEncoding("UTF-8");
        return pph;
    }

    @SneakyThrows
    private static Properties loadProperties(String path){
        InputStream inputStream = null;
        try{
            inputStream = BeanRepository.class.getResourceAsStream(path);
            Properties properties = new Properties();
            properties.load(inputStream);
            return properties;
        }finally{
            try{
                inputStream.close();
            }catch(IOException e){
            }
        }
    }

    public static void initialize(String propPath,Class<?>... annotatedClasses){
        BeanRepository.PROPERTIES = loadProperties(propPath);
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        if(BeanRepository.BEAN_FACTORY != null){
            ctx.setParent(BeanRepository.BEAN_FACTORY);
        }
        ctx = new AnnotationConfigApplicationContext();
        ctx.addBeanFactoryPostProcessor(loadPlaceholderConfigurer(propPath));
        ctx.register(annotatedClasses);
        ctx.refresh();
        BeanRepository.BEAN_FACTORY = ctx;
    }



}
